Developer Documentation

QuickTime 4 API Documentation

QuickTime 4 Reference

| Previous | Chapter Contents | Chapter Top | Next |

Creating an Interpolation Tween

"Interpolation Tweens" discusses tween operations that modify other tween operations by feeding them artificial time values in place of real time. Listing 20 shows how to create an interpolation tween.

Listing 20 Creating an interpolation tween container

OSErr CreateSampleInterpolatedTweenContainer( QTAtomContainer container,
    TimeValue duration, QTAtom *newTweenAtom )
{
    OSErr           err = noErr;
    Handle          pathData = nil;
    
    err = QTRemoveChildren( container, kParentAtomIsContainer );
    if ( err )goto bail;
    
    err = CreateSampleLongTweenContainer( container, 0, duration,
                                            duration, newTweenAtom );
    if ( err ) goto bail;

    pathData = CreateSampleVectorData( 3 );
    if ( ! pathData ) { err = memFullErr; goto bail; }

    err = AddXtoYInterpolatorTweenerForDataSet( container, *newTweenAtom,
                                            *newTweenAtom, 1, pathData );
    if ( err ) goto bail;
bail:
    if ( pathData )DisposeHandle( pathData );
    return err;
}
OSErr AddXtoYInterpolatorTweenerForDataSet( QTAtomContainer container,
    QTAtom sequenceTweenAtom, QTAtom tweenAtom, QTAtomID dataSetID,
    Handle vectorCodecData )
{
    OSErr               err = noErr;
    QTAtomID            interpolationTweenID;
    QTAtom              dataSetAtom, interpolatorTweenAtom, durationAtom,
                        interpolatorIDAtom;
    TimeValue           duration;
    ComponentInstance   ci = nil;
    UInt8               saveState;
    gxPaths             *thePathData;
    long                dataSize, numPoints;
    gxPoint             firstPoint, lastPoint;
    Boolean             ptIsOnPath;
    Fixed               minOutput, maxOutput;
    
    if ( (! container) || (! dataSetID) || (! vectorCodecData) )
                                        { err = paramErr; goto bail; }

    saveState = HGetState( vectorCodecData );

    dataSetAtom = QTFindChildByID( container, tweenAtom, kTweenData,
                                    dataSetID, nil );
    if ( ! dataSetAtom ) { err = cannotFindAtomErr; goto bail; }
    
    // determine duration of tweenEntry so we can use the same duration
    // for the interpolator tween
    durationAtom = QTFindChildByIndex( container, tweenAtom,
                                        kTweenDuration, 1, nil );
    if ( ! durationAtom ) { err = cannotFindAtomErr; goto bail; }
    
    err = QTCopyAtomDataToPtr( container, durationAtom, false,
                                    sizeof(duration), &duration, nil );
    if ( err ) goto bail;
    
    // determine the minOutput and maxOutput values based for the given
    // vector codec data
    err = OpenADefaultComponent( decompressorComponentType,
                                    kVectorCodecType, &ci );
    if ( err ) goto bail;
    
    HLock( vectorCodecData );
    
    err = CurveGetAtomDataFromVectorStream ( ci, vectorCodecData,
                        kCurvePathAtom, &dataSize, (Ptr *)&thePathData );
    if ( err ) goto bail;

    err = CurveCountPointsInPath( ci, thePathData, 0,
                                    (unsigned long *)&numPoints );
    if ( err ) goto bail;

    err = CurveGetPathPoint( ci, thePathData, 0, 0, &firstPoint,
                                &ptIsOnPath );
    if ( err ) goto bail;

    err = CurveGetPathPoint( ci, thePathData, 0, numPoints - 1,
                                &lastPoint, &ptIsOnPath );
    if ( err ) goto bail;

    minOutput = firstPoint.x;
    maxOutput = lastPoint.x;

    // add interolator tween atom with any unique id
    err = AddTweenAtom( container, sequenceTweenAtom, 0,
                        kTweenTypePathXtoY, 0, duration, minOutput,
                        maxOutput, nil, &interpolatorTweenAtom );
    if ( err ) goto bail;

    // so what was that unique id?
    err = QTGetAtomTypeAndID( container, interpolatorTweenAtom, nil,
                                &interpolationTweenID );
    if ( err ) goto bail;

    err = AddDataAtom( container, interpolatorTweenAtom, 1,
                        GetHandleSize( vectorCodecData ),
                        *vectorCodecData, nil, 0, nil );
    if ( err ) goto bail;
    
    // finally, we need to reference this new interpolator tween
    interpolatorIDAtom  = QTFindChildByID( container, tweenAtom,
                            kTweenInterpolationID, dataSetID, nil );
    if ( ! interpolatorIDAtom ) {
        err = QTInsertChild( container, tweenAtom, kTweenInterpolationID,
                            dataSetID, 0, 0, nil, &interpolatorIDAtom );
        if ( err ) goto bail;
    }

    err = QTSetAtomData( container, interpolatorIDAtom,
                sizeof(interpolationTweenID), &interpolationTweenID );
    if ( err ) goto bail;

bail:
    if ( vectorCodecData )
        HSetState( vectorCodecData, saveState );
    return err;
}

To scale the output of an interpolation tween, you add the optional kTweenOutputMaxValue atom and kTweenOutputMinValue atom.


© 1999 Apple Computer, Inc.

| Previous | Chapter Contents | Chapter Top | Next |